package cn.t.facade.user;

import cn.t.converter.user.RoleDeviceDTOConverter;
import cn.t.core.exception.BizException;
import cn.t.core.facade.FacadeImpl;
import cn.t.dto.device.DeviceDTO;
import cn.t.dto.user.RoleDeviceDTO;
import cn.t.core.enums.base.CommonError;
import cn.t.facade.device.DeviceFacade;
import cn.t.model.user.RoleDeviceDO;
import cn.t.model.user.RoleFirmDO;
import cn.t.service.user.RoleDeviceService;
import cn.t.service.user.RoleFirmService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 部门信息表服务编排
 *
 * @author l
 */
@Slf4j
@Service
@AllArgsConstructor
public class RoleDeviceFacade extends FacadeImpl<RoleDeviceDTO, RoleDeviceDO, RoleDeviceDTOConverter, RoleDeviceService> {


    @Override
    public boolean add(RoleDeviceDTO dto) {
        validateDevice(dto);
//        hasDuplicateDevice(dto);
        return service.add(converter.dto2Model(dto));
    }

    @Override
    public boolean update(RoleDeviceDTO dto) {
        validateDevice(dto);
        return service.update(converter.dto2Model(dto));
    }

    public void validateDevice(RoleDeviceDTO dto) {
        List<RoleFirmDO> roleFirm = roleFirmService.findByRoleId(dto.getRoleId());
        if (CollectionUtils.isEmpty(roleFirm)) {
            String errorMessage = String.format("指定的角色未关联任何企业 roleId=%s", dto.getRoleId());
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        if ( roleFirm.size() > 1) {
            String errorMessage = String.format("指定的角色关联多家企业 roleId=%s", dto.getRoleId());
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }
        RoleFirmDO roleFirmDO = roleFirm.get(0);
        DeviceDTO device = existsDeviceInfo(dto);
            if (!roleFirmDO.getFirmId().equals(device.getFirmId())) {
                log.warn("指定的设备不属于当前角色所属公司：{}", dto.getDeviceId());
                throw new BizException(CommonError.BIZ_EXCEPTION, "指定的设备不属于当前角色所属公司");
        }
    }

    public DeviceDTO existsDeviceInfo(RoleDeviceDTO dto) {
        DeviceDTO device = deviceFacade.queryOne(dto.getDeviceId());
        if (device == null || !device.getId().equals(dto.getDeviceId()) || cn.t.enums.device.DeviceStatusEnum.DISABLED.getCode().equals(device.getStatus())) {
            log.warn("指定的设备不存在：{}", dto.getDeviceId());
            throw new BizException(CommonError.BIZ_EXCEPTION, "指定的设备不存在");
        }
        return device;
    }

    public void hasDuplicateDevice(RoleDeviceDTO dto) {

        RoleDeviceDO roleDevice = new RoleDeviceDO();
        roleDevice.setDeviceId(dto.getDeviceId());

        List<RoleDeviceDO> tmp = service.findByModel(roleDevice, 0, 100, null, null);
        if (tmp != null && !tmp.isEmpty()) {
            log.warn("当前角色已绑定此设备：{} - {}", dto.getRoleId(), dto.getDeviceId());
            throw new BizException(CommonError.BIZ_EXCEPTION, "当前角色已绑定此设备");
        }
    }

    public List<RoleDeviceDTO> findByRoleId(Long roleId) {
        List<RoleDeviceDO> list = service.findByRoleId(roleId);
        if (list == null || list.isEmpty()) {
            return null;
        }

        List<RoleDeviceDTO> ret = list.stream().map(converter::model2Dto).collect(Collectors.toList());
        Set<Long> deviceIdSet = list.stream().map(RoleDeviceDO::getDeviceId).collect(Collectors.toSet());

        List<DeviceDTO> tmp = deviceFacade.queryById(deviceIdSet);
        // 使用Stream API将列表转换为Map
        Map<Long, DeviceDTO> deviceMap = tmp.stream().collect(Collectors.toMap(DeviceDTO::getId, Function.identity()));

        ret.forEach(e -> {
            DeviceDTO device = deviceMap.get(e.getDeviceId());
            if (device == null) {
                return;
            }

            e.setDeviceType(device.getDeviceType());
            e.setDeviceName(device.getDeviceName());
        });

        return ret;
    }

    @Autowired
    private DeviceFacade deviceFacade;

@Resource
    private RoleFirmService roleFirmService;

}





